﻿(function ($, undefined) {
    // define the name of the UI component
    var ui_name = "workitemList"

    // initialize object
    var wl = $.workitemList = {
        // default values
        defaults: {},

        setDefaults: function (defaultOptions) {
            this.defaults = $.extend({},
            this.defaults, defaultOptions);
        }
    };

    // static object

    var WorkitemStatus = {
        Ongoing: 0,  // 正在进行中
        Completed: 1,  // 已经完成
        Expired: 2,  // 过期了
        WaitingForConfirm: 3,  // 等待确认
        Ready: 4  // 没有负责人，等待分配
    };
    var classMapping = {
        0: "target-ongoing",  // 正在进行中
        1: "target-finished",  // 已经完成
        2: "target-expired",  // 过期了
        3: "target-waiting-for-confirm",  // 等待确认
        4: "target-ready"// 没有负责人，等待分配
    };


    $.fn.workitemList = function (options) {
        // method calling
        if (typeof options == 'string') {
            var args = Array.prototype.slice.call(arguments, 1),
            res;
            this.each(function () {
                var data = $.data(this, ui_name);
                if (data) {
                    var meth = data[options];
                    if (meth) {
                        var r = meth.apply(this, args);
                        if (res === undefined) {
                            res = r;
                        }
                    }
                }
            });
            if (res !== undefined) {
                return res;
            }
            return this;
        }

        // initialize options
        options = $.extend({},
        wl.defaults, options);

        var convertorBase = {
            GetConvertByColumns: function (columns) {
                var newConvertor = {};
                for (var i = 0; i < columns.length; i++) {
                    newConvertor[columns[i]] = this[columns[i]];
                }

                return newConvertor;
            },

            " ": function (item) {
                var className = classMapping[item.StatusValue];
                var targetStr = '<span class="{ClassName} target-flag">&nbsp;</span>'.replace("{ClassName}", className);
                if (item.Description && item.Description.length > 0) {
                    targetStr += '<a class="ui-icon icon-comment workitem-description" />';
                }

                //add hidden filed to save workitem id
                var hiddenField = '<a class="hidden-workitem-id" name="' + item.Id + '"/>';
                return targetStr + hiddenField;
            },
            "内容-计划-项目": function (item) {
                var titleStr = "";
                titleStr = '<span>{Title}</span>';
                titleStr = titleStr.replace("{Title}", item.Title);

                if (item.Project != null) {
                    var projectElement = '&nbsp;<span class="txtprojectName"><a class="link-project" href="/project/projectinfo/{projectId}" onclick="event.stopPropagation();">{taskName}{projectName}</a></span>';
                    projectElement = projectElement.replace("{projectName}", item.Project.Name);
                    projectElement = projectElement.replace("{projectId}", item.Project.Id);
                    if (item.Task != null) {
                        projectElement = projectElement.replace("{taskName}", item.Task.Name + "&nbsp-&nbsp");
                    }
                    else {
                        projectElement = projectElement.replace("{taskName}", "");
                    }

                    titleStr = titleStr + projectElement
                };

                return titleStr;
            },
            "内容-计划": function (item) {
                var titleStr = "";
                titleStr = '<span>{Title}</span>';
                titleStr = titleStr.replace("{Title}", item.Title);

                if (item.Project != null && item.Task != null) {
                    var taskElement = '&nbsp;<span class="txtprojectName link-project">{taskName}</span>';
                    taskElement = taskElement.replace("{taskName}", item.Task.Name);
                    titleStr = titleStr + taskElement
                };

                return titleStr;
            },
            "内容": function (item) {
                var titleStr = "";
                titleStr = '<span>{Title}</span>';
                titleStr = titleStr.replace("{Title}", item.Title);

                return titleStr;
            },
            "到期": function (item) {
                var planOnStr = "&nbsp;&nbsp;--&nbsp;&nbsp;";
                if (item.PlanOn != null) {
                    planOnStr = Date.fromEpoch(item.PlanOn).toFullDate()
                }
                return planOnStr;
            },
            "完成时间": function (item) {
                return Date.fromEpoch(item.FinishOn).toFullDateTime();
            },
            "创建时间": function (item) {
                return Date.fromEpoch(item.CreateOn).toNiceTime();
            },
            "负责人": function (item) {
                if (item.OwnerName && item.OwnerName != null)
                    return '<center>' + item.OwnerName + '</center>';
                return '<center>&nbsp;--&nbsp;</center>';
            },
            "预计工时": function (item) {
                return item.Points;
            },
            "工时": function (item) {
                return item.Points;
            },
            "操作": function (item) {
                var root = $('<div/>');
                var commandDom = $('<center/>').appendTo(root);
                switch (item.StatusValue) {
                    case WorkitemStatus.Ongoing:
                        $('<span class="btn-finish button green medium">完成任务</span>').appendTo(commandDom);
                        break;
                    case WorkitemStatus.Completed:
                        break;
                    case WorkitemStatus.Expired:
                        $('<span class="btn-extend button rosy medium">任务延期</span>').appendTo(commandDom);
                        break;
                    case WorkitemStatus.WaitingForConfirm:
                        if (item.OwnerId == CurrentUser.Id) {
                            $('<span class="btn-confirm button blue medium">确认收到</span>').appendTo(commandDom)
                        }
                        break;
                    case WorkitemStatus.Ready:
                        $('<span class="btn-takeownership button orange medium">我来负责</span>').appendTo(commandDom);
                        break;

                }
                return root.html();
            }
        };
        var CurrentUser = EzDesk.Service.GetCurrentUser_CacheSync();

        this.each(function () {
            var initCallback;
            var WorkitemList = {

                workitemDataList: [],

                Project: null,
                AvailableProjects: null,
                AvailableMembers: null,

                Service: {},
                Args: {},
                RootElement: null,

                TblMyWorkitemList: null,

                Global: {
                    userId: null
                }
            };

            var _self = this;

            Init();

            // initialize callback
            for (var key in options) {
                var value = options[key];
                if (typeof value == 'function') {
                    // bind callbacks
                    $(_self).bind(key, value);
                }
            }

            function Init() {
                WorkitemList.Args = options;
                initCallback = options.initCallback;
                WorkitemList.RootElement = _self;
                WorkitemList.Service.GetMyOwnWorkitemList = options.GetWorkitemListService;
                //get projects
                if (options.project && options.project != null) {
                    WorkitemList.AvailableProjects = [options.project];
                    WorkitemList.AvailableMembers = options.project.MemberList;
                } else {
                    WorkitemList.AvailableProjects = EzDesk.Service.GetAllProjects_CacheSync();
                    WorkitemList.AvailableMembers = EzDesk.Service.GetAllUserInfo_CacheSync();
                }


                var convert = convertorBase.GetConvertByColumns(WorkitemList.Args.myConvertor);
                WorkitemList.Service.GetMyOwnWorkitemList(function (workitemList) {
                    WorkitemList.workitemDataList = workitemList;
                    bindWorkitem(convert);

                    SetColumnsWidth();
                    if (workitemList.length > 0) {
                        InitEvent();
                    }
                    if (initCallback) {
                        initCallback();
                    }
                });
            };

            function SetColumnsWidth() {
                //Column: target-24,title-auto, planOn-90, create-50,action-100
                var columnWidthMapping = ['26', 'auto', 120, 50, 100];

                for (var i = 0; i < columnWidthMapping.length; i++) {
                    $($(WorkitemList.TblMyWorkitemList).find('thead tr th')[i]).css({ width: columnWidthMapping[i] });
                }
            };

            function bindWorkitem(myConvertor) {
                $(WorkitemList.RootElement).empty();

                if (WorkitemList.workitemDataList.length > 0) {
                    var data = DataConverterForDataTable.convertData(WorkitemList.workitemDataList, myConvertor);

                    data.bPaginate = false;
                    data.bRetrieve = true;
                    data.bFilter = false;
                    data.bSort = false;
                    data.bInfo = false;

                    //操作列居中显示
                    data.fnHeaderCallback = function (nHead, aasData, iStart, iEnd, aiDisplay) {
                        for (var key in nHead.cells) {
                            if (nHead.cells[key].innerHTML == "操作") {
                                $(nHead.cells[key]).css({
                                    'text-align': 'center'
                                });
                            }
                        }
                    };

                    WorkitemList.TblMyWorkitemList = $('<table class="tbl"/>').appendTo(WorkitemList.RootElement);
                    WorkitemList.TblMyWorkitemList.dataTable(data);

                    //斜体
                } else {
                    $(WorkitemList.RootElement).append($('<p class="no-items">没有工作任务</p>'));
                }

            };

            function InitEvent() {
                var setQtipForWorkitem = function (element, tipContent) {
                    element.parents('td').qtip({
                        content: tipContent,
                        position: {
                            my: 'left top',
                            at: 'right top',
                            adjust: {
                                y: 8,
                                x: 0
                            }
                        },
                        style: {
                            classes: 'workitem-ui-tooltip-content ui-tooltip-shadow'
                        },
                        hide: {
                            delay: 300
                        }
                    });
                };

                $(WorkitemList.TblMyWorkitemList).find('tbody tr').each(function (index) {
                    var __self = $(this);
                    var title = __self.find('.workitemName');


                    __self.click(function () {
                        // 关闭其他已经打开的编辑
                        $('.workitemList-tr-edit').each(function (index, item) {
                            $(item).prev().show();
                            $(item).remove();
                        });


                        var workitem = WorkitemList.workitemDataList[index];
                        var isCompleted = workitem.StatusValue == WorkitemStatus.Completed;

                        __self.hide();

                        //dom
                        var trStr = '<tr id="workitemList-item-{Id}"class="workitemList-tr-edit"/>';
                        trStr = trStr.replace("{Id}", workitem.Id);

                        var trDom = $(trStr).append($(__self.find('td')[0]).clone());
                        var infoDom = $('<td class="workitemList-td" colspan="20" />');
                        var formDom = $("#completedWorkitemDetail").tmpl(workitem).appendTo(infoDom);

                        trDom.append(infoDom);
                        trDom.insertAfter(__self);

                        var workitemContainer = $('#workitemList-item-' + workitem.Id);

                        //datePicker
                        workitemContainer.find('.workitemList-PlanOn').wdatepicker({
                            minDate: 0
                        });


                        //项目 && 计划 
                        var clearTaskInfo = function () {
                            workitemContainer.find('.workitemList-hidden-taskId').val('');
                            workitemContainer.find('.workitemList-task-selcetor').val('');
                            workitemContainer.find('.workitem-task-dl').hide();
                        };

                        var clearProjectInfo = function () {
                            workitemContainer.find('.workitemList-hidden-projectId').val('');
                            workitemContainer.find('.workitemList-project-selcetor').val('');
                            workitemContainer.find('.workitem-project-dl').hide();
                        };

                        var bindTaskInfo = function (projectId) {
                            if (projectId) {
                                EzDesk.Service.GetTasksInProject_CacheSync(function (e) {
                                    if (e && e.length > 0) {
                                        workitemContainer.find('.workitem-task-dl').show();
                                        workitemContainer.find('.workitemList-task-selcetor').comboxBindingWithEmptyDefault(e, 'Name', 'Id', ' --- ');
                                        workitemContainer.find('.workitemList-task-selcetor').val(workitem.TaskId);
                                        workitemContainer.find('.workitemList-hidden-taskId').val(workitem.TaskId);
                                    } else clearTaskInfo();
                                }, { projectId: projectId });
                            } else
                                clearTaskInfo();
                        };


                        // 如果这个任务的创建者不是自己，那么不用显示是否追踪任务的按钮
                        if (workitem.CreatorId != CurrentUser.Id) {
                            workitemContainer.find('.workitemList-isTrace-dl').remove();
                        } else {
                            //isTrace
                            var chkTracedChangeCallback = function () {
                                var $label = workitemContainer.find('.lbl-for-ckb');
                                var isTraced = workitemContainer.find('.workitemList-isTrace').attr("checked");
                                if (isTraced) {
                                    $label.removeClass('lbl-ckb-untraced').addClass('lbl-ckb-traced')
                                        .find('span').text('追踪这个任务');
                                } else {
                                    $label.removeClass('lbl-ckb-traced').addClass('lbl-ckb-untraced')
                                        .find('span').text('不追踪这个任务'); ;
                                }
                            };
                            workitemContainer.find('.workitemList-isTrace')
                                .change(chkTracedChangeCallback)
                                .button()
                                .attr("checked", workitem.IsTrace);
                            chkTracedChangeCallback();
                        }

                        //project selector change callback
                        workitemContainer.find('.workitemList-project-selcetor').change(function () {
                            var projectId = workitemContainer.find('.workitemList-project-selcetor').val();
                            workitemContainer.find('.workitemList-hidden-projectId').val(projectId);

                            if (projectId != '') {
                                bindTaskInfo(projectId);
                            } else {
                                clearTaskInfo()
                            }
                        });

                        workitemContainer.find('.workitemList-task-selcetor').change(function () {
                            var taskId = workitemContainer.find('.workitemList-task-selcetor').val();
                            workitemContainer.find('.workitemList-hidden-taskId').val(taskId);
                        });


                        //projects
                        if (WorkitemList.AvailableProjects && WorkitemList.AvailableProjects.length > 0) {
                            workitemContainer.find('.workitem-projcet-dl').show();
                            workitemContainer.find('.workitemList-project-selcetor').comboxBindingWithEmptyDefault(WorkitemList.AvailableProjects, 'Name', 'Id', ' -- ');
                            workitemContainer.find('.workitemList-project-selcetor').val(workitem.ProjectId);
                            workitemContainer.find('.workitemList-hidden-projectId').val(workitem.ProjectId);

                            bindTaskInfo(workitem.ProjectId);
                        } else {
                            clearProjectInfo();
                            clearTaskInfo();
                        }



                        //userSelector
                        if (workitem.StatusValue != WorkitemStatus.Completed) {
                            workitemContainer.find('.workitemList-OwnerName').userSelector({
                                preOpenSelectPanel: function () {
                                    workitemContainer.find('.workitemList-OwnerName').userSelector('initUsers', WorkitemList.AvailableMembers);
                                },
                                canMutipleSelect: false,
                                selectorPanelClosed: function (e, arg) {
                                    $(arg.Users).each(function (index, item) {
                                        workitemContainer.find('.workitemList-OwnerName').html(item.Name);
                                        workitemContainer.find('.workitemList-hiden-OwnerId').val(item.Id);
                                    });
                                }
                            });
                        }

                        //btn click
                        workitemContainer.find('.btnCancel').click(function () {
                            __self.show();
                            workitemContainer.remove();
                        });


                        workitemContainer.find('.btn-submit')
                            .click(function () {
                                updateWorkitem(function (statusInfo) {
                                    __self.show();
                                    workitemContainer.remove();
                                    $.displayStatusInfo(statusInfo);
                                    if (statusInfo.Status == "Success") updateSuccessCallback();
                                });
                            });


                        formDom.slideDown('fast');

                        // 跳转到相应位置
                        $.scroller(workitemContainer[0], 500, 40);
                    });
                });

                $(WorkitemList.RootElement).find('.btn-takeownership').each(function (index) {
                    var $self = $(this);

                    $self.click(function () {
                        var workitemId = $self.parents('tr').find('.hidden-workitem-id').attr('name');
                        if (workitemId == null) return false;

                        EzDesk.Service.DoTakeOwnershipWorkitem_Sync(function (statusInfo) {
                            if (statusInfo.Status == 'Success') Init(WorkitemList.Args);

                            $.displayStatusInfo(statusInfo);
                            publicMethods.Highlight(workitemId, 8000);
                        },
                        {
                            workitemId: workitemId
                        });
                        return false;
                    });
                });



                $(WorkitemList.RootElement).find('.btn-confirm').each(function (index) {
                    var $self = $(this);

                    $self.click(function () {
                        var workitemId = $self.parents('tr').find('.hidden-workitem-id').attr('name');
                        if (workitemId == null) return false;

                        EzDesk.Service.DoConfirmWorkitem_Sync(function (statusInfo) {
                            if (statusInfo.Status == 'Success') Init(WorkitemList.Args);

                            $.displayStatusInfo(statusInfo);
                            publicMethods.Highlight(workitemId, 8000);
                        },
                        {
                            workitemId: workitemId
                        });
                        return false;
                    });
                });


                $(WorkitemList.RootElement).find('.btn-finish').each(function (index) {
                    var self = $(this);

                    self.click(function (event) {
                        var $self = $(this);

                        var $tr = $self.parents('tr');
                        var workitemId = $('.hidden-workitem-id', $tr).attr('name');
                        var workitem = $.grep(WorkitemList.workitemDataList, function (item) {
                            return item.Id == workitemId;
                        })[0];
                        //For template judgement
                        workitem.IsMine = workitem.OwnerId == null || workitem.OwnerId == CurrentUser.Id;

                        event.stopPropagation();

                        var $completeWorkitemPanel = $('#completeWorkitemPanel').tmpl(workitem);
                        $completeWorkitemPanel.contextPanel({
                            parent: this,
                            contextPanelClose: function () {
                                $('.txtHours').clearFields();
                            }
                        });

                        $('.txtHours').select().focus();
                        //完成任务
                        $('.btnFinish')
                            .button({
                                icons: {
                                    primary: "ui-icon-circle-check"
                                },
                                text: true
                            });
                        $('.btnFinish').click(function () {
                            var points = $('.txtHours').val();
                            EzDesk.Service.DoFinishWorkitem(function (statusInfo) {
                                $('.menu-finishWorkitem').contextPanel("close");
                                if (statusInfo.Status == 'Success') Init(WorkitemList.Args);

                                $.displayStatusInfo(statusInfo);
                                finishWorkitemCallBack();
                                publicMethods.Highlight(workitemId, 8000);
                            },
                            {
                                workitemId: workitemId,
                                points: points
                            });
                        });
                        return false;
                    });
                });

                $(WorkitemList.RootElement).find('.btn-extend').each(function (index) {
                    var self = $(this);

                    self.click(function (event) {
                        var $self = $(this);

                        var $tr = $self.parents('tr');
                        var workitemId = $('.hidden-workitem-id', $tr).attr('name');
                        var workitem = $.grep(WorkitemList.workitemDataList, function (item) {
                            return item.Id == workitemId;
                        })[0];

                        //For template judgement
                        event.stopPropagation();

                        var $extendWorkitemPanel = $('#extendWorkitemPanel').tmpl(workitem);
                        $extendWorkitemPanel.contextPanel({
                            parent: this,
                            contextPanelClose: function () {
                                $('.txtNewPlanOn').clearFields();
                            }
                        });

                        var today = Date.fromEpoch(EzDesk.Service.GetCurrentDate_CacheSync());
                        var date = new Date(
                            today.getFullYear(),
                            today.getMonth(),
                            today.getDate()
                        );
                        $('.txtNewPlanOn').wdatepicker({
                            minDate: 0
                        });
                        $('.txtNewPlanOn').datepicker('setDate', date);

                        //完成任务
                        $('.btnExtend')
                            .button({
                                icons: {
                                    primary: "ui-icon-circle-check"
                                },
                                text: true
                            });
                        $('.btnExtend').click(function () {
                            var newPlanOn = $('.txtNewPlanOn').val();
                            EzDesk.Service.DoExtendWorkitem(function (statusInfo) {
                                $('.menu-extendWorkitem').contextPanel("close");
                                if (statusInfo.Status == 'Success') Init(WorkitemList.Args);

                                $.displayStatusInfo(statusInfo);
                                applyForExtendWorkitemCallback();
                                publicMethods.Highlight(workitemId, 8000);
                            }, { id: workitemId, newPlanOn: newPlanOn });
                            return false;
                        });
                    });
                });


                $(WorkitemList.RootElement).find('.target-flag').each(function (index) {
                    //get workitem
                    var $self = $(this);
                    var $tr = $self.parents('tr');
                    var workitemId = $('.hidden-workitem-id', $tr).attr('name');
                    var workitem = $.grep(WorkitemList.workitemDataList, function (item) {
                        return item.Id == workitemId;
                    })[0];

                    var qtipTitle = $("#workitemQTip").tmpl(workitem);
                    setQtipForWorkitem($self, qtipTitle);
                });
            };


            function updateSuccessCallback() {
                Init(WorkitemList.Args);
            };



            function updateWorkitem(callback) {
                $('.workitemList-formWorkItem').ajaxSubmit({
                    success: function (e) {
                        callback(e);
                    }
                });
                return
            };


            /* Callback Triggers
            -----------------------------------------------------------------------------*/

            function finishWorkitemCallBack() {
                $(_self).trigger('finishWorkitemCallBack');
            };

            function applyForExtendWorkitemCallback() {
                $(_self).trigger('applyForExtendWorkitemCallback');
            };



            /* Public Methods
            -----------------------------------------------------------------------------*/

            var publicMethods = {
                // @other public methods
                AddWorkitemCallback: function () {
                    Init(WorkitemList.Args);
                },
                Highlight: function (workitemId, highlightOptions) {

                    var $hiddenFieldList = $.grep($('.hidden-workitem-id'), function (item) {
                        return $(item).attr('name') == workitemId;
                    });

                    if ($hiddenFieldList.length == 1) {
                        $.scroller($hiddenFieldList[0], 500, 70);

                        var $tr = $($hiddenFieldList[0]).parents('tr');

                        $tr.highlight(highlightOptions);
                    }
                }
            };

            $.data(this, ui_name, publicMethods);
        });

        return this;
    };

    // @static methods
})(jQuery);

